﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;
using System.Net.Sockets;

namespace GosafeTest
{
    //public delegate void CurrentIP(string IPAddress);

    class IPMonitor
    {
        private string IPprovider;

         //Delegate used to execute the callback method when the
         //task is complete.
        private SIGGREProto.Server.ExampleCallback callback;
        //private CurrentIP gotIpEvent;
        private SIGGREProto.Server.CurrentIP gotIpEvent;

        public IPMonitor(string IPprovider, SIGGREProto.Server.ExampleCallback callbackDelegate, SIGGREProto.Server.CurrentIP callBackGotIPEvent)
        {
            // TODO: Complete member initialization
            this.IPprovider = IPprovider;
            callback = callbackDelegate;
            this.gotIpEvent = callBackGotIPEvent;
        }

        // The thread procedure performs the task, such as
        // formatting and printing a document, and then invokes
        // the callback delegate with the number of lines printed.
        //public static void getDynamicIP(string URLPRovider)
        public void startMonitorThread(object formToUpdate)
        {
            //for (int i = 0; i < 3; i++)
            while(true)
            {
                Console.WriteLine("Working thread...");
                Thread.Sleep(3000);
                if (callback != null)
                    callback(1);

                //((frmMercatorTest)formToUpdate).txtLog.Text += "IP obtido a partir do provedor <" + IPprovider + ">: " + GetExternalIP(IPprovider) + "\r\n";

                if (gotIpEvent != null)
                    gotIpEvent(GetExternalIP(IPprovider));

            }
        }

        public static  string GetExternalIP(string Provider)
        {
            try
            {
                if ((Provider == null) || (Provider == ""))
                    Provider = "http://automation.whatismyip.com/n09230945.asp";

                HttpWebRequest WebReq = (HttpWebRequest)HttpWebRequest.Create(Provider);
                HttpWebResponse WebRes = (HttpWebResponse)WebReq.GetResponse();

                System.IO.Stream ResStream = WebRes.GetResponseStream();
                StreamReader ResStreamReader = new StreamReader(ResStream, Encoding.UTF8);

                string IP = ResStreamReader.ReadToEnd();

                ResStream.Close();
                WebRes.Close();

                return IP;
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        public static string GetExternalIP()
        {
            return GetExternalIP(null);
        }

        public  static string GetLocalIP()
        {
            //IPAddressMonitorSample1.Class4.DisplayDhcpServerAddresses();
    
            IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
            String MyIp = localIPs[localIPs.Length - 2].ToString();

            //Console.WriteLine(DreamInCode.Snippets.IpFinder.GetExternalIp2());

            IPAddress[] a = Dns.GetHostByName(Dns.GetHostName()).AddressList;
            for (int i = 0; i < a.Length; i++) ;
                //Console.WriteLine("IpAddr[{0}]={1}", i, a[i]);

            //This is a way to get any network address (not necessarily the internet ip) as pointed out in the comments:
            IPAddress host = IPAddress.None;
            foreach (IPAddress ip in Dns.GetHostAddresses(Dns.GetHostName()))
            {
                host = ip;
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    return host.ToString();
                    break;
                }
            }

            IPHostEntry host2;
            string localIP = "?";
            host2 = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host2.AddressList)
            {
                if (ip.AddressFamily.ToString() == "InterNetwork")
                {
                    localIP = ip.ToString();
                }
            }
            return localIP;

            return "";


        }

        //public static void CurrentIP(string IPAddress)
        //{
        //    Console.WriteLine(IPAddress);
        //    //this.updateLog
        //    //this.txtIP.Text = IPAddress;
        //    //txtLog.Text += "IP obtido a partir do provedor <" + IPprovider + ">: " + this.txtIP.Text + "\r\n";
        //}
    }
}


//using System;
//using System.Threading;

//public class Work
//{
//    public static void Main()
//    {
//        // To start a thread using a shared thread procedure, use
//        // the class name and method name when you create the 
//        // ParameterizedThreadStart delegate. C# infers the 
//        // appropriate delegate creation syntax:
//        //    new ParameterizedThreadStart(Work.DoWork)
//        //
//        Thread newThread = new Thread(Work.DoWork);

//        // Use the overload of the Start method that has a
//        // parameter of type Object. You can create an object that
//        // contains several pieces of data, or you can pass any 
//        // reference type or value type. The following code passes
//        // the integer value 42.
//        //
//        newThread.Start(42);

//        // To start a thread using an instance method for the thread 
//        // procedure, use the instance variable and method name when 
//        // you create the ParameterizedThreadStart delegate. C# infers 
//        // the appropriate delegate creation syntax:
//        //    new ParameterizedThreadStart(w.DoMoreWork)
//        //
//        Work w = new Work();
//        newThread = new Thread(w.DoMoreWork);

//        // Pass an object containing data for the thread.
//        //
//        newThread.Start("The answer.");
//    }

//    public static void DoWork(object data)
//    {
//        Console.WriteLine("Static thread procedure. Data='{0}'",
//            data);
//    }

//    public void DoMoreWork(object data)
//    {
//        Console.WriteLine("Instance thread procedure. Data='{0}'",
//            data);
//    }
//}

///* This code example produces the following output (the order 
//   of the lines might vary):

//Static thread procedure. Data='42'
//Instance thread procedure. Data='The answer'
//*/